package com.jlect.swebing.ui.client;

import com.jlect.swebing.ui.client.laf.ContainerUI;
import com.jlect.swebing.ui.client.laf.UIManager;

/**
 * Class represents container for {@link com.jlect.swebing.ui.client.GComponent} objects
 *
 * @author Sergey Kozmin
 * @since 10.11.2007 22:57:38
 */
public class GContainer extends GComponent implements ComponentListener {
    private static final String uiComponentID = "GContainer";

    public static final String COMPONENT_ADDED_PROPERTY_NAME = "component.added";
    public static final String COMPONENT_REMOVED_PROPERTY_NAME = "component.removed";

    private LayoutManager layoutManager;

    public GContainer(LayoutManager layoutManager) {
        setLayoutManager(layoutManager);
        setFocusPolicy(new ChildLinearTraversalPolicy(this));
    }

    public GContainer() {
        this(new FlowLayout());
    }

    public ContainerUI getContainerUI() {
        return (ContainerUI) getUI();
    }

    public void updateUI() {
        setUI(UIManager.getInstance().getUI(this));
    }

    public void addComponent(GComponent component) {
        addComponent(component, null);
    }

    public void addComponent(GComponent component, LayoutConstraint constraint) {
        super.addComponent(component);
        if(layoutManager == null) {
            throw new IllegalStateException("LayoutManager wasn't set. ");
        }
        layoutManager.addLayoutComponent(component, constraint);
        firePropertyChanged(COMPONENT_ADDED_PROPERTY_NAME, null, component);
        component.addComponentListener(this);
    }

    public void removeComponent(GComponent component) {
        super.removeComponent(component);
        componentRemoved(component);
    }

    public GComponent removeComponent(int index) {
        GComponent component = super.removeComponent(index);
        componentRemoved(component);
        return component;
    }

    private void componentRemoved(GComponent component) {
        if(component != null) {
            if(layoutManager != null) {
                layoutManager.removeLayoutComponent(component);
            }
            component.removeComponentListener(this);
            firePropertyChanged(COMPONENT_REMOVED_PROPERTY_NAME, null, component);
        }
    }

    public GComponent getComponent(LayoutConstraint constraint) {
        return layoutManager.getLayoutComponent(constraint);
    }

    public LayoutManager getLayoutManager() {
        return layoutManager;
    }

    public void setLayoutManager(LayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    public void componentResized(ComponentEvent e) {
        //do nothing, because container manages component size
    }

    public void componentMoved(ComponentEvent e) {
        //do nothing, because container manages component location
    }

    public void componentShown(ComponentEvent e) {
        invalidate();
    }

    public void componentHidden(ComponentEvent e) {
        invalidate();
    }

    public void setBounds(int x, int y, int width, int height) {
        super.setBounds(x, y, width, height);
        invalidate();
    }

    public void invalidate() {
        if(layoutManager != null) {
            layoutManager.layoutContainer(this);
        }
    }

    public void componentEligible(GComponent component) {
        if(getComponentsCount() != 0) {
            invalidate();
        }
    }

    public String getUiComponentID() {
        return uiComponentID;
    }
}
